package config

import (
	"log"
	"time"

	"gopkg.in/ini.v1"
)

type AppConfig struct {
	Name        string
	JwtSecret   string
	JwtLifeTime time.Duration
	PageSize    int
	PrefixUrl   string

	RuntimeRootPath string

	ImageSavePath  string
	ImageMaxSize   int
	ImageAllowExts []string

	ExportSavePath string
	QrCodeSavePath string
	FontSavePath   string

	LogSavePath string
	LogSaveName string
	LogFileExt  string
	TimeFormat  string

	Session       bool
	SessionName   string
	SessionKey    string
	SessionMaxAge int
}

var App = &AppConfig{}

type ServerConfig struct {
	RunMode      string
	HttpPort     int
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
}

var Server = &ServerConfig{}

type DatabaseConfig struct {
	Type        string
	User        string
	Password    string
	Host        string
	Name        string
	TablePrefix string
	MaxIdle     int
	MaxOpen     int
}

var Database = &DatabaseConfig{}

type RedisConfig struct {
	Host        string
	Password    string
	DbNum       int
	Prefix      string
	MaxIdle     int
	MaxActive   int
	IdleTimeout time.Duration
}

var Redis = &RedisConfig{}

var cfg *ini.File

// Setup initialize the configuration instance
func Initialize() {
	var err error
	cfg, err = ini.Load("conf/app.ini")
	if err != nil {
		log.Fatalf("Config.Setup, fail to parse 'conf/app.ini': %v", err)
	}

	mapTo("app", App)
	mapTo("server", Server)
	mapTo("database", Database)
	mapTo("redis", Redis)

	App.ImageMaxSize = App.ImageMaxSize * 1024 * 1024
	App.JwtLifeTime = App.JwtLifeTime * time.Second
	Server.ReadTimeout = Server.ReadTimeout * time.Second
	Server.WriteTimeout = Server.WriteTimeout * time.Second
	Redis.IdleTimeout = Redis.IdleTimeout * time.Second
}

// mapTo map section
func mapTo(section string, v interface{}) {
	err := cfg.Section(section).MapTo(v)
	if err != nil {
		log.Fatalf("Cfg.MapTo %s err: %v", section, err)
	}
}

func init() {
	Initialize()
}
